using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using System.IO;
using System.Text;

namespace FEZ_Panda_II_Application1
{
    public delegate void FlightPhaseChangeHandler(FlightPhases newphase);

    public class FlightControl
    {
        static string LockFile="";

        public static void Init(string rootpath)
        {
            Program.Print("Initializing Flight Controller");
            InterruptPort GSEPin = new InterruptPort(AstoXPinMap.GSEPin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            InterruptPort LaunchPin = new InterruptPort(AstoXPinMap.LaunchPin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            InterruptPort ExtendPin = new InterruptPort(AstoXPinMap.ExtendPin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            InterruptPort RetractPin = new InterruptPort(AstoXPinMap.RetractPin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);

            GSEPin.OnInterrupt += new NativeEventHandler(GSEPin_OnInterrupt);
            LaunchPin.OnInterrupt += new NativeEventHandler(LaunchPin_OnInterrupt);
            ExtendPin.OnInterrupt += new NativeEventHandler(ExtendPin_OnInterrupt);
            RetractPin.OnInterrupt += new NativeEventHandler(RetractPin_OnInterrupt);
            LockFile=Path.Combine(rootpath,"lock.txt");

            if (!GSEPin.Read() || LaunchPin.Read() || ExtendPin.Read() || RetractPin.Read())
            {
                Debug.Print("Invalid start state!");
                //Lock();  Think about this line alot!!
            }
        }

        static void GSEPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("GSE Line is " + data2.ToString());
        }

        static void RetractPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Retract Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }
                        
            CurrentPhase = FlightPhases.Retracting;
         
        }

        public static void Lock()
        {
            Program.Print("Locking out changes");
            File.WriteAllBytes(LockFile, Encoding.UTF8.GetBytes(DateTime.Now.Second.ToString()));
        }

        private static bool CheckLocks()
        {
            if (File.Exists(LockFile))
            {
                return true;
            }
            return false;
        }

        static void ExtendPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Extend Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }

            if (CurrentPhase != FlightPhases.Ascent) { return; }
            CurrentPhase = FlightPhases.Extend;
        }

        static void LaunchPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Program.Print("Launrch Line is " + data2.ToString());
            if (data2 != 1) { return; }
            if (CheckLocks()) { return; }

            if (CurrentPhase != FlightPhases.StandingBy) { return; }
            CurrentPhase = FlightPhases.Ascent;
        }


        public static event FlightPhaseChangeHandler FlightPhaseChanged;

        private static FlightPhases _currentPhase;

        public static FlightPhases CurrentPhase
        {
            get { return _currentPhase; }
            set 
            {
                FlightPhases _oldphase = _currentPhase;
                _currentPhase = value; 
                if (_currentPhase != _oldphase)
                {
                    OnPhaseChanged();
                }
                
            }
        }
        

        public static void OnPhaseChanged()
        {
            Program.Print(CurrentPhase.ToString());
            if (FlightPhaseChanged != null)
            {
                FlightPhaseChanged(CurrentPhase);
            }
            
        }


    }

    public enum FlightPhases
    {
        Initializing=0,
        StandingBy=1,
        Ascent=2,
        Extend=3,
        Extending=4,
        Extended=5,
        Retract=6,
        Retracting=7,
        Retracted=8,
        Descent=9,
        Shutdown=10,
    }
}
